package org.zerta.troops.xml;
import org.zerta.troops.common.ActionList;
import org.zerta.troops.common.Area;
import org.zerta.troops.common.Game;
import org.zerta.troops.common.NormalTroop;
import org.zerta.troops.common.Player;
import org.zerta.troops.common.TroopMovement;
import org.zerta.troops.common.TurnData;
import org.zerta.troops.common.Unit;
import org.zerta.troops.common.World;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class TurnDataUnmarshaler {
	
	private World world;
	private Game game;
	
	public TurnDataUnmarshaler ( Game game ) {
		this.game = game;
		this.world = game.getMap();
	}
	
	public TurnData unmarshalTurnData ( Node rootNode ) {
		TurnData tm = new TurnData();
		
		Node n;
		NodeList nodes = rootNode.getChildNodes();
		
		for (int i = 0; i < nodes.getLength(); i++) {
			n = nodes.item(i);
			
			if (n.getNodeType() == Node.ELEMENT_NODE) {
				if (n.getNodeName().equals("PlayerData")) {
					tm.setPlayer( unmarshalPlayerData(n) );
				} else if (n.getNodeName().equals("ActionList")) {
					tm.setActionList( unmarshalActionList(n) );
				} else {
					// Unknown element node in TurnData
				}
			} else {
				// Unknown ndoe-type in TurnData
			}
		}
		
		return tm;
	}
	
	private Player unmarshalPlayerData( Node playerDataNode ) {
		Player p = null;
		Node n;
		NodeList nodes = playerDataNode.getChildNodes();
		
		for (int i = 0; i < nodes.getLength(); i++) {
			n = nodes.item(i);
			
			if (n.getNodeType() == Node.ELEMENT_NODE) {
				if (n.getNodeName().equals("Name")) {
					String name = unmarshalText(n);
					p = game.findPlayer(name);
					if (p == null) {
						System.err.println("Could not find player with name " + name);
					}
				} else {
					// Unknown element in PlayerData
				}
			} else {
				// Unknown node-type in PlayerData
			}
		}
		
		return p;
	}
	
	private ActionList unmarshalActionList( Node actionListNode ) {
		ActionList al = new ActionList();
		
		Node n;
		NodeList nodes = actionListNode.getChildNodes();
		
		for (int i = 0; i < nodes.getLength(); i++) {
			n = nodes.item(i);
			
			if (n.getNodeType() == Node.ELEMENT_NODE) {
				if (n.getNodeName().equals("TroopMovement")) {
					al.addAction( unmarshalTroopMovement(n) );
				} else {
					// Unexpected element in ActionList
				}
			} else {
				// Unexpected node-type in ActionList
			}
		}
		
		return al;
	}
	
	private TroopMovement unmarshalTroopMovement( Node troopMovementNode ) {
		TroopMovement tm = new TroopMovement();
		
		Node n;
		
		NodeList nodes = troopMovementNode.getChildNodes();
		
		for (int i = 0; i < nodes.getLength(); i++) {
			n = nodes.item(i);
			
			if (n.getNodeType() == Node.ELEMENT_NODE) {
				
				if (n.getNodeName().equals("Origin")) {
					
					Area originArea = world.findArea(unmarshalText( n ));
					if (originArea == null) {
						System.err.println("Could not find origin area");
						return null;
					}
					tm.setOrigin( originArea );
					
				} else if (n.getNodeName().equals("Destination")) {
					
					Area destinationArea = world.findArea(unmarshalText( n ));
					if (destinationArea == null) {
						System.err.println("Could not find destination area");
						return null;
					}
					tm.setDestination( destinationArea );
					
				} else if (n.getNodeName().equals("Unit")) {
					
					String unitName = unmarshalText( n );
					
					if (unitName.equals("NormalTroop")) {
						
						Unit unit = new NormalTroop();
						tm.setUnit(unit);
						
					} else {
						// Unknown unit type
						System.err.println("Unknown unit");
						return null;
						
					}
					
				} else if (n.getNodeName().equals("Num")) {
					
					Integer num = new Integer(unmarshalText( n ));
					tm.setNum(num.intValue());
				}
			} else {
				// Unknown node-type in TroopMovement
			}
		}
		return tm;
	}
	
	private String unmarshalText ( Node textNode ) {
		StringBuffer buffer = new StringBuffer();
		
		Node n;
		NodeList nodes = textNode.getChildNodes();
		
		for (int i = 0; i < nodes.getLength(); i++) {
			n = nodes.item(i);
			if (n.getNodeType() == Node.TEXT_NODE) {
				buffer.append( n.getNodeValue() );
			} else {
				// Unknown node-type in unmarshalText
			}
		}
		return buffer.toString();
	}
	
	/*
	private String unmarshalAttribute ( Node node, String name, String defaultValue ) {
		Node n = node.getAttributes().getNamedItem(name);
		return (n != null) ? (n.getNodeValue()) : (defaultValue);
	}
	*/


}
